﻿// Shader-Based-Image-Processing (SBIP)
// http://code.google.com/p/sbip/
//
// Copyright © Frank Nagl, 2009-2011
// admin@franknagl.de
//
namespace SBIP.Filter
{
    using System;

    /// <summary>
    /// Gaussian blur filter with a <see cref="Size"/>x<see cref="Size"/> 
    /// filter kernel.
    /// </summary>
    /// <remarks>
    /// <para>Filter implements the Gaussian operator with flexibel kernel 
    /// values of a <see cref="Size"/>x<see cref="Size"/> kernel matrix.
    /// </para>
    /// <para>The Gaussian filter calculates each pixel
    /// of the result image as weighted sum of the correspond pixel and 
    /// its neighbors in the source image. The weighted sum is divided by 
    /// the divisor before putting it into result image.
    /// </para>
    /// <para>
    /// Note: This filter works only for XNA 4.0 HidhDef profile. 
    /// See flag <c><see cref="Processor.HighDef"/>.</c>
    /// </para>
    /// 
    /// <para>Sample usage:</para>
    /// <code>
    /// Bitmap image = new Bitmap("cathedral.jpg");
    ///
    /// // 1. Offline rendering of images
    /// // create Processor, used as rendering framework
    /// Processor processor = new Processor( );
    /// // starts Processor
    /// processor.Begin( image );
    /// // create GaussianBlur filter
    /// GaussianBlur filter = new GaussianBlur( );
    /// processor.Filter = filter;
    /// // optional: configure filter
    /// ...
    /// // apply the filter, render to bitmap  
    /// Bitmap resultImage = processor.RenderToBitmap( );
    /// resultImage.Save( "GaussianBlur.jpg", ImageFormat.Jpeg );
    /// // apply the filter, render to texture
    /// // Texture2D resultTexture = processor.RenderToTexture( );
    /// processor.End( );
    ///  
    /// // 2. Online rendering of videos or images
    /// // create any windows control for rendering in
    /// Form myForm = new Form
    /// {
    ///     Width = 1280,
    ///     Height = 720
    /// };
    /// // starts Processor
    /// processor.Begin( "Video.avi", myForm );
    /// // create GaussianBlur filter
    /// filter = new GaussianBlur( );
    /// processor.Filter = filter;
    /// // optional: configure filter
    /// ...
    /// // apply the filter
    /// myForm.Show( );
    /// while ( myForm.Created )
    /// {
    ///     processor.Render( );
    ///     Application.DoEvents( );
    /// }
    /// processor.End( );
    /// </code>
    /// 
    /// <para><b>Initial image:</b></para>
    /// <img src="../../Cathedral.jpg" width="500" height="338" />
    /// <para><b>Result image (<see cref="GaussianBlurLight.Sigma"/> = 5.0f; 
    /// <see cref="GaussianBlur.Size"/> = 15):</b></para>
    /// <img src="../../GaussianBlur.jpg" width="500" height="338" />
    /// </remarks>
    public sealed class GaussianBlur : GaussianBlurLight
    {
        #region effect properties
        // Default: 7
        private int size;

        /// <summary>
        /// Kernel size, [3, 41].
        /// </summary>
        /// 
        /// <remarks><para>Size of Gaussian kernel.</para>
        /// 
        /// <para>Default value is set to <b>7</b>.</para>
        /// </remarks>
        /// 
        public int Size
        {
            get { return size; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("Size" + InitMsg);
                // get new size value
                size = Math.Max(3, Math.Min(41, value | 1));
                Effect.Parameters["Size"].SetValue(size);
            }
        }
        #endregion effect properties

        /// <summary>
        /// Initializes a new instance of the <see cref="GaussianBlur"/> class.
        /// </summary>
        public GaussianBlur()
        {
            EffectFile = "GaussianBlur";
            RealtimeCapable = true; 
        }

        /// <summary>
        /// Defines Laplace algorithm properties.
        /// </summary>
        protected override void PostInit()
        {
            base.PostInit();
            Size = 7;
        }
    }
}
